package org.eclipse.equinox.spring.osgi;

/**
 * This file is part of org.springframework.equinox.deployer. 
 * Copyright (C) olivier.evalet@genebio.com and genebio team
 * 
 * org.springframework.equinox.deployer is free software: you can redistribute
 * it and/or modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, either version 3 of the License,
 * or (at your option) any later version.
 * 
 * org.springframework.equinox.deployer is distributed in the hope that it will
 * be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
 * Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * org.springframework.equinox.deployer. If not, see <http://www.gnu.org/licenses/>.
 * 
 * Special thanks for Bernd Kolb the first author of this file  
 */



import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.Servlet;

import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.service.http.HttpService;
import org.osgi.util.tracker.ServiceTracker;
import org.springframework.context.ApplicationContext;

/**
 * A {@link ServiceTracker} implementation which waits until the
 * {@link ApplicationContext} is available and gives the implementor a
 * {@link HttpService} and the {@link ApplicationContext} to register resources
 * and servlets on this service.
 * 
 * @author Bernd Kolb
 * 
 */
public abstract class AppContextAwareHttpServiceTracker extends ServiceTracker {

	private ApplicationContext applicationContext;
	private List<HttpService> httpServices = new ArrayList<HttpService>();
	private Map<String, String> contextConfig = new HashMap<String, String>();
	private List<SpringServlet> servlets;

	public AppContextAwareHttpServiceTracker(BundleContext context) {
		super(context, HttpService.class.getName(), null);
		
	}

	public void setAppContext(ApplicationContext applicationContext) {
		this.applicationContext = applicationContext;
		checkAndCall();
	}
	


	private void checkAndCall() {
		if (applicationContext == null || httpServices.size() == 0) {
			return;
		}
		try {
			for (HttpService httpService : httpServices) {
				addServiceInternal(applicationContext, httpService);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	@Override
	public Object addingService(ServiceReference reference) {
		Object service = super.addingService(reference);
		if (service instanceof HttpService) {
			addHttpService((HttpService) service);
		}
		return service;
	}

	private void addHttpService(HttpService addingService) {
		this.httpServices.add(addingService);
		checkAndCall();

	}

	/**
	 * @param appContext
	 *            the {@link ApplicationContext} for the bundle in which the
	 *            service tracker has been initialized
	 * @param httpService
	 *            Reference to service being added to this
	 *            <code>ServiceTracker</code> object.
	 * @throws Exception
	 */
	protected abstract void addServiceInternal(ApplicationContext appContext,
			HttpService httpService) throws Exception;

	public void setContextConfig(Map<String, String> contextConfig) {
		this.contextConfig=contextConfig;
	}
	
	public String getConfig(String name, String def){
		String v=contextConfig.get(name);
		if (v!=null)
			return v;
		return def;
	}

	public void setServlets(List<SpringServlet> servlets) {
		this.servlets=servlets;
	}
	
	public List<SpringServlet> getServlets(){
		return servlets;
	}

}
